#pragma once
#include "mfcore.hpp"
#include<list>

class InputBox:public Control{
    protected:
    class BaseDo{
        public:
        string* text;
        vector<U8Unit> units;
        size_t tbegin,ubegin,_tbegin,_tend,_ubegin,_uend;//_为绘制区间 其它为操作区间
        virtual ~BaseDo();
        virtual void UnDo(InputBox* p)=0;
        virtual void ReDo(InputBox* p)=0;
    };
    //新增,撤销时删掉
    class DoAdd:public BaseDo{
        public:
        DoAdd(string* t,vector<U8Unit>* u,size_t tb,size_t ub);
        void UnDo(InputBox* p);
        void ReDo(InputBox* p);
    };
    class DoRemove:public BaseDo{
        public:
        DoRemove(string* t,vector<U8Unit>::iterator begin,vector<U8Unit>::iterator end,
        size_t tb,size_t ub,size_t _tb,size_t _te,size_t _ub,size_t _ue);
        void UnDo(InputBox* p);
        void ReDo(InputBox* p);
    };
    class DoReplace:public BaseDo{
        public:
        string* text2;
        vector<U8Unit> units2;
        size_t _ub,_ue,_tb,_te;//插入前的位置
        //先插入的 后删除的
        DoReplace(string* t,vector<U8Unit>* u,string* t2,vector<U8Unit>::iterator begin,vector<U8Unit>::iterator end,
        size_t tb,size_t ub,size_t _tb,size_t _te,size_t _ub,size_t _ue);
        void UnDo(InputBox* p);
        void ReDo(InputBox* p);
        ~DoReplace()override;
    };
    Task* _task;
    int _x;//按下时设置
    static void ListenMouse(void* i);
    SDL_Color _text_color;
    Font* _font;
    string* _text;
    SDL_Texture* _t,*_alert;//缓存
    size_t _begin_text,_end_text,_begin_unit,_end_unit,_cur_text,_cur_unit;
    size_t _s_tbegin,_s_tend,_s_ubegin,_s_uend;
    vector<U8Unit>* _units;//u8统一占2格 存相对字符串起始的偏移量
    int _flash_count;
    bool _flash;
    list<BaseDo*> *redo,*undo;
    unsigned int _max_do,_cur_do;//撤销重做的最大次数

    void _cut();
    void _begin_do();
    //计算当前编辑位置在当前显示区域外时的新显示区域
    void _process_outside(BaseDo* temp);
    void _copy();
    void _paste();
    void _select_all();

    virtual void OnTextChanged()=0;
    virtual void OnInputFinish()=0;

    public:
    bool _input_start;
    SDL_Color background,line_color,select_color,disable_color,cursor_color;

    const string* text();
    SDL_Color text_color();
    Font* font();

    InputBox(Window* window,SDL_Rect& rect,SDL_Color background=Color::White,Font* font=default_font,const char* alert="input..",
    const char* init_text="",SDL_Color _text_color=Color::Black,SDL_Color select_color=Color::SkyBlueGray,SDL_Color line_color=Color::Black,
    SDL_Color disable_color=Color::Gray,SDL_Color cursor_color=Color::Red,unsigned int max_do=64);
    InputBox(Window* window);
    void SetSize(int w,int h)override;
    ~InputBox();
    //可NULL
    void SetAlert(const char* new_alert);
    void SetText(const char* new_text,SDL_Color _text_color=Color::Black,SDL_Color select_color=Color::SkyBlueGray);
    void _mouse_move(int x,int y);
    //空时不会进行任何操作
    void _input(const char* text);
    void _key_down(SDL_Keysym& sym)override;
    void _press(int x,int y,int clicks,unsigned char key);
    void _release(int x,int y,int clicks,unsigned char key);
    void _draw();
    void OnFocus();
    void LoseFocus();
    static void Cut(InputBox* i);
    static void Copy(InputBox* i);
    static void Paste(InputBox* i);
    static void SelectAll(InputBox* i);
};

class InputItem:public MenuText{
    public:
    static void Copy(MenuItem* i);
    static void Cut(MenuItem* i);
    static void Paste(MenuItem* i);
    static void SelectAll(MenuItem* i);
    InputBox* box;
    InputItem(Window* w,const char* t);
    ~InputItem();
    bool DrawCheck();
};
//初始化右键菜单
void InitInputMenu(Window*);